/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2000-2001 Intel Corporation. All Rights Reserved.
//
//  Description:
//      Intel(R) JPEG library for X platform 
//
********************************************************************************/
#include "_ijx.h"

extern const Ipp8u _nIZigZagIndex[64];

/******************************************************************************
// Name:            ijEncodeScanData_Baseline
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pMCUBuf: Identifies MCU coefficient buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
// Output Arguments:
//    pDecodeState: Identifies IJDECODESTATE strcuture.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijEncodeScanData_Baseline(IJBITTREAMSTATE  *pStream,
                                    IJENCODESTATE *pEncodeState)
{
    int x, y;

    int nHMCUPos, nVMCUPos;
    int nHMCUCount, nVMCUCount;
    int nMCUWidth, nMCUHeight;
    int nMCUPadWidth, nMCUPadHeight;
    int nImageMCUHOffset, nImageMCUVOffset;
    int nTempImageStep;
    int nProcessedBitsLen;

    const Ipp8u *pImageData;
    int   nImageStep;

    Ipp16s **ppCoeffBuf;
    Ipp8u *pTempImageData;
    const Ipp8u  *pImageCur;
    IppiSize srcSize, dstSize;

    IJBUFFER *pIJXBuffer;
    IJMCUSPEC *pMCUSpec;
    IIPIMAGESPEC *pImageSpec;
    IJENPROCESSSPEC *pProcSpec;


//    IJX_ASSERT(NULL!=pIJXBuffer);
//    IJX_ASSERT(NULL!=pStream);
//    IJX_ASSERT(NULL!=pEncodeState);

    pIJXBuffer=&(pEncodeState->bufSpec);
    pMCUSpec=&(pEncodeState->mcuSpec);
    pImageSpec=&(pEncodeState->imageSpec);
    pProcSpec=&(pEncodeState->procSpec);

    pImageData=pIJXBuffer->paImageBufCur[0];
    nImageStep=pIJXBuffer->naImageStep[0];

    nHMCUPos=pEncodeState->nHMCUCurPos;
    nVMCUPos=pEncodeState->nVMCUCurPos;
    nHMCUCount=pMCUSpec->nHMCUCount;
    nVMCUCount=pMCUSpec->nVMCUCount;
    nMCUWidth=pMCUSpec->nMCUWidth;
    nMCUHeight=pMCUSpec->nMCUHeight;
    nMCUPadWidth=pMCUSpec->nMCUPadWidth;
    nMCUPadHeight=pMCUSpec->nMCUPadHeight;

    nImageMCUHOffset=((pImageSpec->nBitsPerpixel)>>3)*nMCUWidth;
    nImageMCUVOffset=nImageStep*nMCUHeight;

    dstSize.width=nMCUWidth;
    dstSize.height=nMCUHeight;

    ppCoeffBuf=pIJXBuffer->paMCUCoeffBufCur;
    nTempImageStep=pMCUSpec->nImageMCUStep;
    pTempImageData=pIJXBuffer->pAuxMCUDataTempBuf;

    nProcessedBitsLen=pStream->nUsedBufBitsLen;

    for (y=nVMCUPos; y<nVMCUCount; y++) {
        pImageCur=pImageData;
        for (x=nHMCUPos; x<nHMCUCount; x++) {
            pProcSpec->funcMCUColorConvert(pImageCur, nImageStep, ppCoeffBuf);
            pProcSpec->funcMCUTransform(ppCoeffBuf, (const Ipp16u **)(pEncodeState->paIdxDCTQuantTable));
            pProcSpec->funcHuffmanEncoder( (const Ipp16s **)ppCoeffBuf, pStream, pEncodeState);
            pImageCur+=nImageMCUHOffset;
        } //for (x=nHMCUPos; x<nHMCUCount; x++) 

        if (0<nMCUPadWidth) {
            srcSize.width=nMCUPadWidth;
            srcSize.height=nMCUHeight;

            pProcSpec->funcCopyExpand(pImageCur, nImageStep, srcSize, 
                                      pTempImageData, nTempImageStep, dstSize);
            pProcSpec->funcMCUColorConvert(pTempImageData, nTempImageStep, ppCoeffBuf);
            pProcSpec->funcMCUTransform(ppCoeffBuf, (const Ipp16u **)(pEncodeState->paIdxDCTQuantTable));
            pProcSpec->funcHuffmanEncoder((const Ipp16s **)ppCoeffBuf, pStream, pEncodeState);

        }//if (0<nMCUPadWidth)
        pImageData+=nImageMCUVOffset;
    } //for (y=nVMCUPos; y<nVMCUCount; y++)

    if (0<nMCUPadHeight) {
        srcSize.width=nMCUWidth;
        srcSize.height=nMCUPadHeight;
        for (x=nHMCUPos; x<nHMCUCount; x++) {
            pProcSpec->funcCopyExpand(pImageData, nImageStep, srcSize, 
                                      pTempImageData, nTempImageStep, dstSize);
            pProcSpec->funcMCUColorConvert(pTempImageData, nTempImageStep, ppCoeffBuf);
            pProcSpec->funcMCUTransform(ppCoeffBuf, (const Ipp16u **)(pEncodeState->paIdxDCTQuantTable));
            pProcSpec->funcHuffmanEncoder((const Ipp16s **)ppCoeffBuf, pStream, pEncodeState);

            pImageData+=nImageMCUHOffset;
        } //for (x=nHMCUPos; x<nHMCUCount; x++)
        if (0<nMCUPadWidth) {
            srcSize.width=nMCUPadWidth;
            pProcSpec->funcCopyExpand(pImageData, nImageStep, srcSize, 
                                      pTempImageData, nTempImageStep, dstSize);
            pProcSpec->funcMCUColorConvert(pTempImageData, nTempImageStep, ppCoeffBuf);
            pProcSpec->funcMCUTransform(ppCoeffBuf, (const Ipp16u **)(pEncodeState->paIdxDCTQuantTable));
            pProcSpec->funcHuffmanEncoder((const Ipp16s **)ppCoeffBuf, pStream, pEncodeState);
        } //if (0<nMCUPadWidth)
    } //if (0<nMCUPadHeight)

//    pEncodeState->nHMCUCurPos=x;
//    pEncodeState->nVMCUCurPos=y;
    nProcessedBitsLen=pStream->nUsedBufBitsLen-nProcessedBitsLen;
    pEncodeState->counter.nProcessedBitsLen+=nProcessedBitsLen;
    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijEncodeScanData_ABaseline
// Description:     Encoding scan data for Baseline mode
// Input Arguments:
//      pImageData: Identifies image data buffer.
//      nImageStep: Indicates the step of 'pImageData' buffer.
//         pMCUBuf: Identifies MCU coefficient buffer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
// Output Arguments:
//    pDecodeState: Identifies IJDECODESTATE strcuture.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijEncodeScanData_ABaseline(IJBITTREAMSTATE  *pStream,
                                     IJENCODESTATE *pEncodeState)
{
    int i;
    int nMCUCount;
    int nProcessedBitsLen;
    Ipp16s **ppCoeffBuf;

    IJBUFFER *pIJXBuffer;
    IJMCUSPEC *pMCUSpec;
    IJENPROCESSSPEC *pProcSpec;
    
//    IJX_ASSERT(NULL!=pIJXBuffer);
//    IJX_ASSERT(NULL!=pEncodeState);

    pIJXBuffer=&(pEncodeState->bufSpec);
    ppCoeffBuf=pIJXBuffer->paImgCoeffBufCur;
    pMCUSpec=&(pEncodeState->mcuSpec);
    pProcSpec=&(pEncodeState->procSpec);

    nMCUCount=pMCUSpec->nTotalMCUCount;

    nProcessedBitsLen=pStream->nUsedBufBitsLen;

    for (i=0; i<nMCUCount; i++) {
        pProcSpec->funcHuffmanEncoder( (const Ipp16s **)ppCoeffBuf, 
                                       pStream,
                                       pEncodeState);
        pProcSpec->funcAdjustMCUBuf(pMCUSpec, pIJXBuffer);
    }

    ijResetBuffers(pIJXBuffer);
    pEncodeState->counter.nDRICounter=pEncodeState->nRstInterval;
    pEncodeState->counter.nRSTCounter=0;
    nProcessedBitsLen=pStream->nUsedBufBitsLen-nProcessedBitsLen;
    pEncodeState->counter.nProcessedBitsLen+=nProcessedBitsLen;

    return IJX_RTCODE_OK;
}

/* EOF */
